const jsdoc2md = require("jsdoc-to-markdown");
const fs = require("fs");
const path = require("path");
const fetch = require("node-fetch");

const groups = [
  { dir: "object", title: "Objects", order: 301 },
  { dir: "control", title: "Controls", order: 401 },
  { dir: "visual", title: "Visual & Experience", order: 501 },
];

const supertags = ["TimeSeries"];

const currentTagsUrl = "https://api.github.com/repos/heartexlabs/label-studio/contents/docs/source/tags";

// header with tag info and autogenerated order
// don't touch whitespaces
const infoHeader = (name, group, isNew = false) => `---
title: ${name}
type: tags
order: ${groups.find(g => g.dir === group).order++}
${isNew ? "is_new: t\n" : ""}---

`;

const outputDir = path.resolve(__dirname + "/../docs");

fs.mkdirSync(outputDir, { recursive: true });

// get list of already exsting tags if possible to set `is_new` flag
fetch(currentTagsUrl)
  .then(res => (res.ok ? res.json() : null))
  .then(list => list && list.map(file => file.name.replace(/.md$/, "")))
  .catch(() => null)
  .then(tags => {
    function processTemplate(t, dir, supertag) {
      // all tags are with this kind and leading capital letter
      if (t.kind !== "member" || !t.name.match(/^[A-Z]/)) return;
      const name = t.name.toLowerCase();
      // there are no new tags if we didn't get the list
      const isNew = tags ? !tags.includes(name) : false;
      const header = supertag ? `## ${t.name}\n\n` : infoHeader(t.name, dir, isNew);

      let str = jsdoc2md
        .renderSync({ data: [t], "example-lang": "html" })
        // add header with info instead of header for github
        // don't add any header to subtags as they'll be inserted into supertag's doc
        .replace(/^(.*?\n){3}/, header)
        // remove useless Kind: member
        .replace(/\*\*Kind\*\*.*?\n/, "### Parameters\n")
        .replace(/\*\*Example\*\*\s*\n/g, "### Example\n")
        // move comments from examples to description
        .replace(/```html[\n\s]*<!-- (.*?) -->[\n\s]*/g, "\n$1\n\n```html\n")
        // change example language if it looks like JSON
        .replace(/```html[\n\s]*([[{])/g, "```json\n$1");

      if (supertags.includes(t.name)) {
        console.log(`Fetching subtags of ${t.name}`);
        const templates = jsdoc2md.getTemplateDataSync({ files: `${t.meta.path}/${t.name}/*.js` });
        const subtags = templates
          .map(t => processTemplate(t, dir, t.name))
          .filter(Boolean)
          .join("\n\n");
        if (subtags) {
          // insert before the first example or just at the end of doc
          str = str.replace(/(### Example)|$/, `${subtags}\n$1`);
        }
      }

      return str;
    }

    for (let { dir, title } of groups) {
      console.log("## " + title);
      const inputFile = path.resolve(__dirname + "/../src/tags/" + dir + "/*.js");
      const templateData = jsdoc2md.getTemplateDataSync({ files: inputFile });

      templateData.forEach(t => {
        const name = t.name.toLowerCase();
        const str = processTemplate(t, dir);
        if (!str) return;
        fs.writeFileSync(path.resolve(outputDir, `${name}.md`), str);
      });
    }
  });
